const fs = require('fs');
const path = require('path');
const xml2js = require('xml2js');
const util = require('util');
const typeMapping = require('./typeMapping');

const parser = new xml2js.Parser();
const readFile = util.promisify(fs.readFile);
const writeFile = util.promisify(fs.writeFile);

// 解析 Java 文件以提取字段注释
async function parseJavaComments(filePath) {
    const content = await readFile(filePath, 'utf8');
    const lines = content.split('\n');
    const comments = {};
    let currentComment = '';

    for (const line of lines) {
        const trimmedLine = line.trim();
        if (trimmedLine.startsWith('/**') || trimmedLine.startsWith('* ')) {
            currentComment += trimmedLine.replace(/^\/\*\*|\*\/$|^\* /g, '') + ' ';
        } else if (trimmedLine.startsWith('private') && currentComment.length > 0) {
            const parts = trimmedLine.split(/\s+/);
            const fieldName = parts[2].replace(';', '');
            comments[fieldName] = currentComment.trim();
            currentComment = ''; // Reset for next field
        }
    }
    return comments;
}

async function readXmlFiles(dir, outputFile, entityDir) {
    const directoryPath = path.join(__dirname, dir);
    let files = fs.readdirSync(directoryPath);
    files = files.filter(file => file.endsWith('.xml'));
    let allSql = '';

    for (const file of files) {
        const filePath = path.join(directoryPath, file);
        const javaFilePath = path.join(__dirname, entityDir, file.replace('.xml', '.java'));
        console.log(`Processing ${file}...`);
        const javaComments = await parseJavaComments(javaFilePath);  // Parse corresponding Java file for comments
        const content = await readFile(filePath);
        const result = await parser.parseStringPromise(content);
        const sql = generateSql(result, javaComments);
        allSql += sql + '\n\n';  // Accumulate SQL statements, and add interval
    }

    await writeFile(path.join(__dirname, outputFile), allSql);  // Write to single file
    console.log(`All SQL generated successfully into ${outputFile}`);
}


function generateSql(result, javaComments) {
  const mapper = result.mapper;
  const tableName = mapper.sql.find(sql => sql.$.id === 'TableName')._.trim();  // 清理空白
  const primaryKey = mapper.resultMap[0].result[0].$.column; // 假设第一个result映射为主键
  const columns = mapper.resultMap[0].result.map(col => {
      const colType = typeMapping[col.$.jdbcType] || 'varchar(255)';
      const isPrimary = col.$.column === primaryKey;
      const fieldName = col.$.property;
      let commentText = javaComments[fieldName] || col.$.property; // 从Java文件获取注释，如果没有则使用属性名
      if (isPrimary) {
          commentText = "主键";  // 特别为主键字段设置注释
      }
      const comment = ` COMMENT '${commentText}'`;
      return `  \`${col.$.column}\` ${colType}${isPrimary ? " NOT NULL AUTO_INCREMENT" : " DEFAULT NULL"}${comment}`;
  });

  const sql = `-- ${tableName} 表
CREATE TABLE \`${tableName}\` (
${columns.join(',\n')},
PRIMARY KEY (\`${primaryKey}\`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='${tableName} 表';`;

  return sql;
}

// Example call
const entityDir = 'entity'; // Assuming entity files are in the 'entity' directory relative to the script
readXmlFiles('mapper', 'xml_to_sql_2.sql', entityDir).catch(err => {
    console.error("Error occurred:", err);
});
